﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonLib;
using ElementLib.Interface;
using System.Windows.Forms;
using HalconDotNet;
using System.Windows;
namespace ElementLib
{
    public class LC : IComplexMes
    {
        private int type;
        private string name;
        public delegate void drawFunc(string type);
        private LinePack linePack;
        private CirclePack circlePack;
        private Output output;
        private double supOffsetRow, supOffsetColumn;
        private static int[] existCount = new int[5];

        private List<string> nameList;
        private SupportLine supportLine;

        public SupportLine SupportLine
        {
            get { return supportLine; }
            set { if (supportLine != null) supportLine.Dispose(); supportLine = new SupportLine(value); }
        }

        public string Name { get { return name; } set { name = value; } }

        public List<string> NameList
        {
            get { return nameList; }
            set
            {

                foreach (var item in value)
                {
                    nameList.Add(item);
                }
            }
        }

        public void Unload()
        {
            linePack.Unload();
            circlePack.Unload();
        }
        public void Dispose()
        {
            linePack.Dispose();
            circlePack.Dispose();
            linePack = null;
            circlePack = null;
        }

        public LinePack LinePack
        {
            get { return linePack; }
            set { linePack = value; }
        }
        public CirclePack CirclePack
        {
            get { return circlePack; }
            set { circlePack = value; }
        }
        public LC()
        {
            nameList = new List<string>();

        }

        public LC(LC lc)
        {
            supOffsetRow = lc.supOffsetRow;
            supOffsetColumn = lc.supOffsetColumn;
            name = lc.name;
            nameList = new List<string>();
            type = lc.type;
            output = new Output(lc.output);
            linePack = new LinePack(lc.linePack);
            circlePack = new CirclePack(lc.circlePack);
        }

        public Output Rs
        {
            set { output = value; }
            get { return output; }
        }
        public int Type { get { return type; } set { type = value; } }

        public bool loadElem(List<IElemPack> ieps)
        {
            linePack = new LinePack();
            circlePack = new CirclePack();
            string tips = "只能选择一个圆和一条边";
            if (ieps.Count > 2)
            {
                MessageBox.Show(tips);
                return false;
            }
            for (int i = 0; i < ieps.Count; i++)
            {
                string name = ieps[i].GetType().FullName;
                if (name == ConstValue.TYPE_POINTPACK)
                {
                    MessageBox.Show("混有其他基本元素");
                    return false;
                }
                else if(name == ConstValue.TYPE_CIRCLEPACK){
                    if(circlePack != null)
                    {
                        MessageBox.Show(tips);
                        return false;
                    }
                    circlePack = new CirclePack((CirclePack)ieps[i]);
                }
                else if(name == ConstValue.TYPE_LINEPACK)
                {
                    if (linePack != null)
                    {
                        MessageBox.Show(tips);
                        return false;
                    }
                    linePack = new LinePack((LinePack)ieps[i]);
                }

            }
            ieps.Clear();
            return true;
        }
        public void CompleteChildElem()
        {

        }

        public void ApplyChange(string mode)
        {


            switch (type)
            {
                case ConstValue.MEASURE_LC_Cross:
                    if (mode == "add") name = "lcCross" + existCount[0]++;
                    break;
                case ConstValue.MEASURE_LC_DIST:
                    if (mode == "add") name = "lcDist" + existCount[1]++;
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 规划阶段用这个
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        public Output Execute(FindMethod method)
        {

            if(linePack == null)
            {
                var rs = method(nameList[0], ConstValue.LINE);
                if (rs != null)
                    linePack = new LinePack() { L = new Line((Line)rs) };
            }
            if(circlePack == null)
            {
                var rs = method(nameList[1], ConstValue.CIRCLE);
                if (rs != null)
                    circlePack = new CirclePack() { C = new Circle((Circle)rs) };
            }

            if (linePack == null || circlePack == null) throw new Exception();
            Output output = null;
            HTuple row, column, rowBegin, rowEnd, colBegin, colEnd,minDist,maxDist,nr,nc,dist;
            List<Point> tempPoints = new List<Point>();
            switch (type)
            {
                case ConstValue.MEASURE_LC_Cross:
                 
                    GeoMethod.LC_Cross(linePack.Contours(), circlePack.Contours(), out row, out column);

                    for (int i = 0; i < row.TupleLength(); i++)
                    {
                        tempPoints.Add(new Point(row[i], column[i]));
                    }
                    output = new Output(tempPoints, ConstValue.POINT);
                    break;
                case ConstValue.MEASURE_LC_DIST:
                    supOffsetRow = supportLine.RowOffset;
                    supOffsetColumn = supportLine.ColumnOffset;
                    HOperatorSet.FitLineContourXld(linePack.Contours(), "turkey", -1, 0, 5, 2.0, out rowBegin, out colBegin, out rowEnd, out colEnd, out nr, out nc, out dist);
                    HOperatorSet.DistanceLc(circlePack.Contours(), rowBegin, colBegin, rowEnd, colEnd, out minDist, out maxDist);
                    double[] rs2 = { minDist, maxDist };
                    output = new Output(rs2, ConstValue.DISTANCE);
                    break;
                default:
                    break;
            }
            Rs = output;
            return output;
           
        }

        /// <summary>
        /// 测量阶段用这个
        /// </summary>
        /// <param name="image"></param>
        /// <param name="homMat2D"></param>
        /// <param name="angle"></param>
        /// <param name="add"></param>
        /// <param name="find"></param>
        /// <param name="addSupline"></param>
        void IComplexMes.Execute(HObject image, HTuple homMat2D, HTuple angle, AddToList add, FindMethod find, AddSupline addSupline)
        {
                IElemPack ptr=null;
                if (circlePack.IsDetectType())
                {
                    ptr = find(circlePack.Name, ConstValue.CIRCLE);
                    if (ptr != null) circlePack = (CirclePack)ptr;
                    else
                    {
                        var circle = circlePack.Detect(image, homMat2D);
                        if (circle == null) { MessageBox.Show("没有检测到"); throw new Exception(); }
                    }
                }
                else
                {
                    ptr = find(circlePack.Name, ConstValue.CIRCLE);
                    if (ptr == null)
                    {
                        MessageBox.Show("没有检测到"); throw new Exception();
                    }
                }
                circlePack.C = new Circle((Circle)ptr);
                add(circlePack, ConstValue.CIRCLE);

                if (linePack.IsDetectType())
                {
                    ptr = find(linePack.Name, ConstValue.LINE);
                    if (ptr != null) linePack = (LinePack)ptr;
                    else
                    {
                        var line = linePack.Detect(image, homMat2D);
                        if (line == null) { MessageBox.Show("没有检测到"); throw new Exception(); }
                    }
                }
                else
                {
                    ptr = find(linePack.Name, ConstValue.LINE);
                    if (ptr == null)
                    {
                        MessageBox.Show("没有检测到"); throw new Exception();
                    }
                }
                linePack.L = new Line((Line)ptr);
                add(linePack, ConstValue.LINE);






                HTuple row, column, rowBegin, rowEnd, colBegin, colEnd, minDist, maxDist, nr, nc, dist;
              
                switch (type)
                {
                    case ConstValue.MEASURE_LC_Cross:

                        GeoMethod.LC_Cross(linePack.Contours(), circlePack.Contours(), out row, out column);

                        for (int i = 0; i < row.TupleLength(); i++)
                        {
                            Point p = new  Point(row[i], column[i]);
                            add(new PointPack() { P = p, Name = p.Name },ConstValue.POINT);      
                        }
                        break;
                    case ConstValue.MEASURE_LC_DIST:
                        supOffsetRow = supportLine.RowOffset;
                        supOffsetColumn = supportLine.ColumnOffset;
                        HOperatorSet.FitLineContourXld(linePack.Contours(), "turkey", -1, 0, 5, 2.0, out rowBegin, out colBegin, out rowEnd, out colEnd, out nr, out nc, out dist);
                        HOperatorSet.DistanceLc(circlePack.Contours(), rowBegin, colBegin, rowEnd, colEnd, out minDist, out maxDist);
                        double[] rs2 = { minDist, maxDist };
                        output = new Output(rs2, ConstValue.DISTANCE);
                        break;
                    default:
                        break;
                }
        }

         

        }
    
}
